#pragma once
#include "Logger.h"
#include "Noncopyable.h"
#include "Timestamp.h"
#include <functional>
#include <memory>

class EventLoop;
// 封装了sockfd和其感兴趣的event，如EPOLLIN和EPOLLOUT，还绑定了poller返回的具体事件
class Channel : Noncopyable
{
  public:
    using EventCallBack = std::function<void()>;
    using ReadEventCallBack = std::function<void(Timestamp)>;

    Channel(EventLoop *loop, int fd);
    ~Channel();
    // fd得到poller通知后处理事件，调用相应的回调方法
    void handleEvent(Timestamp receiveTime);
    // 设置回调函数对象
    void setReadCallback(ReadEventCallBack cb)
    {
        readCallback_ = std::move(cb);
    }
    void setWriteCallback(EventCallBack cb)
    {
        writeCallback_ = std::move(cb);
    }
    void setCloseCallback(EventCallBack cb)
    {
        closeCallback_ = std::move(cb);
    }
    void setErrorCallback(EventCallBack cb)
    {
        errorCallback_ = std::move(cb);
    }
    // 防止channel被手动remove，channel还在执行回调函数
    void tie(const std::shared_ptr<void> &);
    int fd() const
    {
        return fd_;
    }
    int events() const
    {
        return events_;
    }
    void setRevents(int revt)
    {
        revents_ = revt;
    }

    // 设置fd相应的事件状态
    void enableReading()
    {
        events_ |= kReadEvent;
        update();
    }
    void disableReading()
    {
        events_ &= ~kReadEvent;
        update();
    }
    void enableWriting()
    {
        events_ |= kWriteEvent;
        update();
    }
    void disableWriting()
    {
        events_ &= ~kWriteEvent;
        update();
    }
    void disableAll()
    {
        LOG_TRACE("trace");
        events_ = kNoneEvent;
        update();
    }
    // 返回fd当前的事件状态
    bool isNoneEvent() const
    {
        return events_ == kNoneEvent;
    }
    bool isReading() const
    {
        return events_ & kReadEvent;
    }
    bool isWriting() const
    {
        return events_ & kWriteEvent;
    }

    int index()
    {
        return index_;
    }
    void setIndex(int index)
    {
        index_ = index;
    }
    // 当前channel所属的loop
    EventLoop *ownerLoop()
    {
        return loop_;
    }
    void remove();

  private:
    static const int kNoneEvent;
    static const int kReadEvent;
    static const int kWriteEvent;

    void update();

    void handleEventWithGuard(Timestamp receiveTime);

    EventLoop *loop_; // 事件循环
    int fd_;          // fd 是 Poller 监听的对象
    int events_;      // 记录感兴趣的事件
    int revents_;     // Poller 返回的具体发生的事件
    int index_;

    std::weak_ptr<void> tie_;
    bool tied_;

    // Channel中能够获知fd最终发生的具体的事件revents，所以它负责调用具体事件的回调操作
    ReadEventCallBack readCallback_;
    EventCallBack writeCallback_;
    EventCallBack closeCallback_;
    EventCallBack errorCallback_;
}; // class Channel
